/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using System.Threading.Tasks;
using System;

namespace NetProtocol.Server {
	/// <summary>
	/// 战斗逻辑模块
	/// module : battleLogic
	/// </summary>
	public interface SNetBattleLogic : INetServerModule {
		Dictionary<int, MessageHandler> INetServerModule.GetModuleFunction()
        {	
            return new()
            {
                { NetMessageId.battleLogic_ReadyToStart, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_ReadyToStart, "Recv->" + data.ToString());
#endif
		                ReadyToStartRequest _data = (ReadyToStartRequest)data;
						return CS_ReadyToStart(session);
		            } 
            	},
                { NetMessageId.battleLogic_RequestLeave, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_RequestLeave, "Recv->" + data.ToString());
#endif
		                RequestLeaveRequest _data = (RequestLeaveRequest)data;
		                CS_RequestLeave(session);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.battleLogic_CastSkill, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_CastSkill, "Recv->" + data.ToString());
#endif
		                CastSkillRequest _data = (CastSkillRequest)data;
						return CS_CastSkill(session, _data.skillPOD);
		            } 
            	},
                { NetMessageId.battleLogic_CastComplete, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_CastComplete, "Recv->" + data.ToString());
#endif
		                CastCompleteRequest _data = (CastCompleteRequest)data;
		                CS_CastComplete(session);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.battleLogic_AutoBattle, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_AutoBattle, "Recv->" + data.ToString());
#endif
		                AutoBattleRequest _data = (AutoBattleRequest)data;
						return CS_AutoBattle(session, _data.openPOD);
		            } 
            	},
                { NetMessageId.battleLogic_Substitute, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_Substitute, "Recv->" + data.ToString());
#endif
		                SubstituteRequest _data = (SubstituteRequest)data;
		                CS_Substitute(session, _data.oldGuid);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.battleLogic_SkipBattle, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.battleLogic_SkipBattle, "Recv->" + data.ToString());
#endif
		                SkipBattleRequest _data = (SkipBattleRequest)data;
		                CS_SkipBattle(session);
		                return VoidMessageResult.Instance;
		            } 
            	},
            };
        }
        
        Dictionary<int, Func<IReceiveMessage>> INetServerModule.GetModuleRequest() 
        {
	        return new ()
	        {
	        	{NetMessageId.battleLogic_ReadyToStart, ()=> new ReadyToStartRequest()},
	        	{NetMessageId.battleLogic_RequestLeave, ()=> new RequestLeaveRequest()},
	        	{NetMessageId.battleLogic_CastSkill, ()=> new CastSkillRequest()},
	        	{NetMessageId.battleLogic_CastComplete, ()=> new CastCompleteRequest()},
	        	{NetMessageId.battleLogic_AutoBattle, ()=> new AutoBattleRequest()},
	        	{NetMessageId.battleLogic_Substitute, ()=> new SubstituteRequest()},
	        	{NetMessageId.battleLogic_SkipBattle, ()=> new SkipBattleRequest()},
	        };
	    }
        
#region Server-side Interface
		/// <summary>
        /// 
        /// </summary>
	    protected ReadyToStartResult CS_ReadyToStart(ISession session);
		/// <summary>
        ///  请求离开
        /// </summary>
    	protected bool CS_RequestLeave(ISession session);
		/// <summary>
        /// 释放技能
        /// </summary>
	    protected CastSkillResult CS_CastSkill(ISession session, BattleSkillPOD skillPOD);
		/// <summary>
        /// 
        /// </summary>
    	protected bool CS_CastComplete(ISession session);
		/// <summary>
        /// 
        /// </summary>
	    protected AutoBattleResult CS_AutoBattle(ISession session, BattleAutoPOD openPOD);
		/// <summary>
        /// 
        /// </summary>
    	protected bool CS_Substitute(ISession session, int oldGuid);
		/// <summary>
        /// 
        /// </summary>
    	protected bool CS_SkipBattle(ISession session);
#endregion
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
        public CastSkillResult SC_CastSkillResult(Task<CastSkillResult> future){return new CastSkillResult(future);}
        public CastSkillResult SC_CastSkillResult(int code){return new CastSkillResult(code);}
		/// <summary>
        /// 
        /// </summary>
        public AutoBattleResult SC_AutoBattleResult(Task<AutoBattleResult> future){return new AutoBattleResult(future);}
        public AutoBattleResult SC_AutoBattleResult(int code, bool open){return new AutoBattleResult(code, open);}
        public AutoBattleResult SC_AutoBattleResult(int code){return new AutoBattleResult(code);}
		/// <summary>
        /// 
        /// </summary>
        public ReadyToStartResult SC_ReadyToStartResult(Task<ReadyToStartResult> future){return new ReadyToStartResult(future);}
        public ReadyToStartResult SC_ReadyToStartResult(int code){return new ReadyToStartResult(code);}
		/// <summary>
        ///  进入战斗		
        /// </summary>
		public bool SC_NotifyEnter(ISession session, BattleEnterPOD battle){
	        return NetProtocolHelper.SendMessage(session, new NotifyEnter(battle));
	    }
	    public void SC_NotifyEnter_Broadcast(List<ISession> sessions, BattleEnterPOD battle){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyEnter(battle));
	    }
		/// <summary>
        ///  退出战斗	
        /// </summary>
		public bool SC_NotifyLeave(ISession session){
	        return NetProtocolHelper.SendMessage(session, new NotifyLeave());
	    }
	    public void SC_NotifyLeave_Broadcast(List<ISession> sessions){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyLeave());
	    }
		/// <summary>
        ///  开始战斗
        /// </summary>
		public bool SC_NotifyStart(ISession session){
	        return NetProtocolHelper.SendMessage(session, new NotifyStart());
	    }
	    public void SC_NotifyStart_Broadcast(List<ISession> sessions){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyStart());
	    }
		/// <summary>
        ///  通知战斗结束，技能等可能会后结束？
        /// </summary>
		public bool SC_NotifyEnd(ISession session, BattleEndPOD endPOD){
	        return NetProtocolHelper.SendMessage(session, new NotifyEnd(endPOD));
	    }
	    public void SC_NotifyEnd_Broadcast(List<ISession> sessions, BattleEndPOD endPOD){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyEnd(endPOD));
	    }
		/// <summary>
        ///  通知数据更新	
        /// </summary>
		public bool SC_NotifyUpdates(ISession session, List<BattleUpdatePOD> updates){
	        return NetProtocolHelper.SendMessage(session, new NotifyUpdates(updates));
	    }
	    public void SC_NotifyUpdates_Broadcast(List<ISession> sessions, List<BattleUpdatePOD> updates){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyUpdates(updates));
	    }
#endregion

#region Messages
	public class CastSkillResult : MessageResult {
	    public CastSkillResult(Task<CastSkillResult> future): base(future) { }
		public CastSkillResult(int code): base(code) { }
		public new CastSkillResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<CastSkillResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.battleLogic_CastSkillResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_CastSkillResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "BattleLogic.SC_CastSkillResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class AutoBattleResult : MessageResult {
	    private bool open;
	    public AutoBattleResult(Task<AutoBattleResult> future): base(future) { }
		public AutoBattleResult(int code): base(code) { }
		public new AutoBattleResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal AutoBattleResult(int code, bool open){
	        this.code = code;
	        this.open = open;
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<AutoBattleResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.battleLogic_AutoBattleResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_AutoBattleResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_boolean(open);
			return si_p;
		}
		public override string ToString() {
    		return "BattleLogic.SC_AutoBattleResult { "
			+ "code="
			+ code
			+ ", open="
			+ open
			+" }";
		}
	}
	public class ReadyToStartResult : MessageResult {
	    public ReadyToStartResult(Task<ReadyToStartResult> future): base(future) { }
		public ReadyToStartResult(int code): base(code) { }
		public new ReadyToStartResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<ReadyToStartResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.battleLogic_ReadyToStartResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_ReadyToStartResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "BattleLogic.SC_ReadyToStartResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class NotifyEnter : MessageNotify {
		private BattleEnterPOD battle;
		public NotifyEnter(BattleEnterPOD battle) {
		    this.battle = battle;
		}
		public override int GetMessageId() {return NetMessageId.battleLogic_NotifyEnter;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_NotifyEnter;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(battle);
			return si_p;
		}
		public override string ToString() {
			return "BattleLogic.SC_NotifyEnter { "
			+ "battle="
			+ battle
			+" }";
		}
	}
	public class NotifyLeave : MessageNotify {
		public NotifyLeave() {
		}
		public override int GetMessageId() {return NetMessageId.battleLogic_NotifyLeave;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_NotifyLeave;
			si_p.StartWrite();
			return si_p;
		}
		public override string ToString() {
			return "BattleLogic.SC_NotifyLeave { "
			+" }";
		}
	}
	public class NotifyStart : MessageNotify {
		public NotifyStart() {
		}
		public override int GetMessageId() {return NetMessageId.battleLogic_NotifyStart;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_NotifyStart;
			si_p.StartWrite();
			return si_p;
		}
		public override string ToString() {
			return "BattleLogic.SC_NotifyStart { "
			+" }";
		}
	}
	public class NotifyEnd : MessageNotify {
		private BattleEndPOD endPOD;
		public NotifyEnd(BattleEndPOD endPOD) {
		    this.endPOD = endPOD;
		}
		public override int GetMessageId() {return NetMessageId.battleLogic_NotifyEnd;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_NotifyEnd;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(endPOD);
			return si_p;
		}
		public override string ToString() {
			return "BattleLogic.SC_NotifyEnd { "
			+ "endPOD="
			+ endPOD
			+" }";
		}
	}
	public class NotifyUpdates : MessageNotify {
		private List<BattleUpdatePOD> updates;
		public NotifyUpdates(List<BattleUpdatePOD> updates) {
		    this.updates = updates == null ? null : new (updates);
		}
		public override int GetMessageId() {return NetMessageId.battleLogic_NotifyUpdates;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_NotifyUpdates;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_list_pod(updates);
			return si_p;
		}
		public override string ToString() {
			return "BattleLogic.SC_NotifyUpdates { "
			+ "updates="
			+ updates.ToString<BattleUpdatePOD>()
			+" }";
		}
	}
	private class ReadyToStartRequest : IReceiveMessage
    {
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_ReadyToStart; }
        public override string ToString()
        {
            return "BattleLogic.ReadyToStart";
        }
    }
	private class RequestLeaveRequest : IReceiveMessage
    {
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_RequestLeave; }
        public override string ToString()
        {
            return "BattleLogic.RequestLeave";
        }
    }
	private class CastSkillRequest : IReceiveMessage
    {
		internal BattleSkillPOD skillPOD;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            skillPOD = _in.HasRemaining() ? _in.Read_pod<BattleSkillPOD>(BattleSkillPOD.DynamicFactory) : default;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_CastSkill; }
        public override string ToString()
        {
            return "BattleLogic.CastSkill"+ ", skillPOD="+ skillPOD;
        }
    }
	private class CastCompleteRequest : IReceiveMessage
    {
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_CastComplete; }
        public override string ToString()
        {
            return "BattleLogic.CastComplete";
        }
    }
	private class AutoBattleRequest : IReceiveMessage
    {
		internal BattleAutoPOD openPOD;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            openPOD = _in.HasRemaining() ? _in.Read_pod<BattleAutoPOD>(BattleAutoPOD.DynamicFactory) : default;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_AutoBattle; }
        public override string ToString()
        {
            return "BattleLogic.AutoBattle"+ ", openPOD="+ openPOD;
        }
    }
	private class SubstituteRequest : IReceiveMessage
    {
		internal int oldGuid;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            oldGuid = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_Substitute; }
        public override string ToString()
        {
            return "BattleLogic.Substitute"+ ", oldGuid="+ oldGuid;
        }
    }
	private class SkipBattleRequest : IReceiveMessage
    {
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
		}
        public int GetMessageId() { return NetMessageId.battleLogic_SkipBattle; }
        public override string ToString()
        {
            return "BattleLogic.SkipBattle";
        }
    }
	}
#endregion
}